package com.elinkway.infinitemovies.bigdata;

import android.text.TextUtils;

import com.apkfuns.logutils.LogUtils;
import com.elinkway.infinitemovies.ui.activity.play.PlayerUtils;
import com.elinkway.infinitemovies.utils.StringUtil;
import com.lvideo.http.bean.LVideoBaseBean;
import com.lvideo.http.bean.LVideoDataHull;

import java.util.UUID;

public class BigDataPlayReporter {

    private long buffer_start = 0;
    private long buffer_time = 0;// ut
    private String uuid; // +1逻辑
    private int retry_time = 0;
    private int progress = 0;// prg
    private String stream_type = PlayerUtils.VT_MP4_350; // vt 默认为标清流 (乐视资源上报)(外网也需上报)
    private long duration; // vlen
    private String cid;
    private String vid;
    private String pid;

    private String ref;
    private String url;
    private String playType = BigDataConstants.TY_ONLINE; // ty---默认为点播
    private String py = "";

    private String errorType;
    private String errorCode = "";
    private boolean isBufferSuccess = false;
    private boolean isErrorReported = false;

    private int pt;
    private String zid;
    private String lid;
    private String nt;
    private int owner;
    private String mid;

    private String ac;
    private String source;

    public String getPy() {
        return py;
    }

    public void setPy(String py) {
        this.py = py;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public BigDataPlayReporter setAc(String ac) {
        this.ac = ac;
        return this;
    }

    public BigDataPlayReporter setPt(int pt) {
        this.pt = pt;
        return this;
    }

    public BigDataPlayReporter setZid(String zid) {
        this.zid = zid;
        return this;

    }

    public BigDataPlayReporter setLid(String lid) {
        this.lid = lid;
        return this;
    }

    public BigDataPlayReporter setNt(String nt) {
        this.nt = nt;
        return this;
    }

    public BigDataPlayReporter setOwner(int owner) {
        this.owner = owner;
        return this;
    }

    public BigDataPlayReporter setMid(String mid) {
        this.mid = mid;
        return this;
    }

    private class BigDataPlayerPlayProcessTask extends BigDataBaseTask {
        @Override
        public boolean execute() {
            LVideoDataHull<LVideoBaseBean> result = BigDataApi.postPlay(null, ac,
                    pt, "", getUUID(), cid, pid, vid, duration, 0,
                    playType, stream_type, url, ref, py, progress, zid, lid,
                    nt, "", System.currentTimeMillis(), owner, mid, source);
            if (result.getDataType() == LVideoDataHull.DataType.DATA_PARSER_IS_NULL) {
                retry_time = 0;
                return true;
            } else {
                return false;
            }
        }
    }

    private class BigDataPlayerInitTask extends BigDataBaseTask {
        @Override
        public boolean execute() {
            LVideoDataHull<LVideoBaseBean> result = BigDataApi.postPlay(null,
                    BigDataConstants.PLAY_AC_INIT, pt, "", getUUID(),
                    cid, pid, vid, duration, 0, playType, stream_type, url,
                    ref, py, progress, zid, lid, nt, BigDataConstants.CAID,
                    System.currentTimeMillis(), owner, mid, source);
            if (result.getDataType() == LVideoDataHull.DataType.DATA_PARSER_IS_NULL) {
                retry_time = 0;
                return true;
            } else {
                return false;
            }
        }
    }

    private class BigDataAdStartTask extends BigDataBaseTask {
        @Override
        public boolean execute() {
            LVideoDataHull<LVideoBaseBean> result = BigDataApi.postPlay(null,
                    BigDataConstants.PLAY_AC_AD_START, pt, "", getUUID(),
                    cid, pid, vid, duration, 0, playType, stream_type, url,
                    ref, py, progress, zid, lid, nt, BigDataConstants.CAID,
                    System.currentTimeMillis(), owner, mid, source);
            if (result.getDataType() == LVideoDataHull.DataType.DATA_PARSER_IS_NULL) {
                retry_time = 0;
                return true;
            } else {
                return false;
            }
        }
    }

    private class BigDataAdEndTask extends BigDataBaseTask {
        @Override
        public boolean execute() {
            LVideoDataHull<LVideoBaseBean> result = BigDataApi.postPlay(null,
                    BigDataConstants.PLAY_AC_AD_END, pt, "", getUUID(),
                    cid, pid, vid, duration, 0, playType, stream_type, url,
                    ref, py, progress, zid, lid, nt, BigDataConstants.CAID,
                    System.currentTimeMillis(), owner, mid, source);
            if (result.getDataType() == LVideoDataHull.DataType.DATA_PARSER_IS_NULL) {
                retry_time = 0;
                return true;
            } else {
                return false;
            }
        }
    }

    private class BigDataPlayStartTask extends BigDataBaseTask {
        @Override
        public boolean execute() {
            LVideoDataHull<LVideoBaseBean> result = BigDataApi.postPlay(null,
                    BigDataConstants.PLAY_AC_PLAY, pt, "", getUUID(),
                    cid, pid, vid, duration, retry_time, playType, stream_type,
                    url, ref, py, progress, zid, lid, nt, "",
                    System.currentTimeMillis(), owner, mid, source);
            if (result.getDataType() != LVideoDataHull.DataType.DATA_PARSER_IS_NULL
                    && retry_time < 10) {
                retry_time++;
                BigDataStats.post(new BigDataPlayStartTask());
            } else {
                retry_time = 0;
                return true;
            }
            return false;
        }
    }

    private class BigDataPlayTimeTask extends BigDataBaseTask {
        @Override
        public boolean execute() {
            LVideoDataHull<LVideoBaseBean> result = BigDataApi.postPlay(null,
                    BigDataConstants.PLAY_AC_TIME, pt, "", getUUID(),
                    cid, pid, vid, duration, retry_time, playType, stream_type,
                    url, ref, py, progress, zid, lid, nt, "",
                    System.currentTimeMillis(), owner, mid, source);
            if (result.getDataType() != LVideoDataHull.DataType.DATA_PARSER_IS_NULL
                    && retry_time < 10) {
                retry_time++;
                BigDataStats.post(new BigDataPlayTimeTask());
            } else {
                retry_time = 0;
                return true;
            }
            return false;
        }
    }

    private class BigDataPlayErrorTask extends BigDataBaseTask {
        @Override
        public boolean execute() {
            LVideoDataHull<LVideoBaseBean> result = BigDataApi.postError(null,
                    errorType, errorCode,
                    nt, getUUID());
            if (result.getDataType() != LVideoDataHull.DataType.DATA_PARSER_IS_NULL
                    && retry_time < 10) {
                retry_time++;
                BigDataStats.post(new BigDataPlayErrorTask());
            } else {
                retry_time = 0;
                return true;
            }
            return false;
        }

    }

    private class BigDataPlayEndTask extends BigDataBaseTask {
        @Override
        public boolean execute() {
            LVideoDataHull<LVideoBaseBean> result = BigDataApi.postPlay(null,
                    BigDataConstants.PLAY_AC_END, pt, "", getUUID(), cid, pid,
                    vid, duration, retry_time, playType, stream_type, url, ref,
                    py, progress, zid, lid, nt, "", System.currentTimeMillis(),
                    owner, mid, source);
            if (result.getDataType() != LVideoDataHull.DataType.DATA_PARSER_IS_NULL
                    && retry_time < 10) {
                retry_time++;
                BigDataStats.post(new BigDataPlayEndTask());
            } else {
                reset();
                return true;
            }
            return false;
        }

    }

    private class BigDataPlayFinishTask extends BigDataBaseTask {
        @Override
        public boolean execute() {
            LVideoDataHull<LVideoBaseBean> result = BigDataApi.postPlay(null,
                    BigDataConstants.PLAY_AC_FINISH, pt, "", getUUID(), cid, pid,
                    vid, duration, retry_time, playType, stream_type, url, ref,
                    py, progress, zid, lid, nt, "", System.currentTimeMillis(),
                    owner, mid, source);
            if (result.getDataType() != LVideoDataHull.DataType.DATA_PARSER_IS_NULL
                    && retry_time < 10) {
                retry_time++;
                BigDataStats.post(new BigDataPlayFinishTask());
            } else {
                reset();
                return true;
            }
            return false;
        }
    }

    private class BigDataPlayPauseTask extends BigDataBaseTask {
        @Override
        public boolean execute() {
            LVideoDataHull<LVideoBaseBean> result = BigDataApi.postPlay(null,
                    BigDataConstants.PLAY_AC_PAUSE, pt, "", getUUID(), cid, pid,
                    vid, duration, retry_time, playType, stream_type, url, ref,
                    py, progress, zid, lid, nt, "", System.currentTimeMillis(),
                    owner, mid, source);
            if (result.getDataType() != LVideoDataHull.DataType.DATA_PARSER_IS_NULL
                    && retry_time < 10) {
                retry_time++;
                BigDataStats.post(new BigDataPlayPauseTask());
            } else {
                reset();
                return true;
            }
            return false;
        }
    }

    /**
     * 拖拽上报
     */
    private class BigDataPlayDragTask extends BigDataBaseTask {
        @Override
        public boolean execute() {
            LVideoDataHull<LVideoBaseBean> result = BigDataApi.postPlay(null,
                    BigDataConstants.PLAY_AC_DRAG, pt, "", getUUID(), cid, pid,
                    vid, duration, retry_time, playType, stream_type, url, ref,
                    py, progress, zid, lid, nt, "", System.currentTimeMillis(),
                    owner, mid, source);
            if (result.getDataType() != LVideoDataHull.DataType.DATA_PARSER_IS_NULL
                    && retry_time < 10) {
                retry_time++;
                BigDataStats.post(new BigDataPlayDragTask());
            } else {
                reset();
                return true;
            }
            return false;
        }
    }

    /**
     * 暂停后恢复上报
     */
    private class BigDataPlayResumeTask extends BigDataBaseTask {
        @Override
        public boolean execute() {
            LVideoDataHull<LVideoBaseBean> result = BigDataApi.postPlay(null,
                    BigDataConstants.PLAY_AC_RESUME, pt, "", getUUID(), cid, pid,
                    vid, duration, retry_time, playType, stream_type, url, ref,
                    py, progress, zid, lid, nt, "", System.currentTimeMillis(),
                    owner, mid, source);
            if (result.getDataType() != LVideoDataHull.DataType.DATA_PARSER_IS_NULL
                    && retry_time < 10) {
                retry_time++;
                BigDataStats.post(new BigDataPlayResumeTask());
            } else {
                reset();
                return true;
            }
            return false;
        }
    }

    /**
     * 切换清晰度上报
     */
    private class BigDataPlayTgTask extends BigDataBaseTask {
        @Override
        public boolean execute() {
            LVideoDataHull<LVideoBaseBean> result = BigDataApi.postPlay(null,
                    BigDataConstants.PLAY_AC_TG, pt, "", getUUID(), cid, pid,
                    vid, duration, retry_time, playType, stream_type, url, ref,
                    py, progress, zid, lid, nt, "", System.currentTimeMillis(),
                    owner, mid, source);
            if (result.getDataType() != LVideoDataHull.DataType.DATA_PARSER_IS_NULL
                    && retry_time < 10) {
                retry_time++;
                BigDataStats.post(new BigDataPlayTgTask());
            } else {
                reset();
                return true;
            }
            return false;
        }
    }

    public String getUUID() {
        if (TextUtils.isEmpty(uuid)) {
            uuid = generateUUID() + "_0";
        }
        return uuid;
    }

    /**
     * 清晰度切换
     *
     * @param streamType
     */
    public void onStreamChange(String streamType) {
        LogUtils.d("play post streamType changed: " + streamType);
        setStreamType(streamType);
        updateUuid();
        LogUtils.d("play post StreamChange and uuid changed: uuid is " + this.uuid);
        onPlayTg();
    }

    // 后缀加1
    private void updateUuid() {
        int lastIndex = uuid.length() - 1;
        char lastNum = uuid.charAt(lastIndex);
        int curNum = Integer.valueOf(String.valueOf(lastNum)) + 1;
        uuid = uuid.substring(0, lastIndex) + "" + curNum + "";
    }

    /**
     * 从后台回前台更新uuid
     */
    public void onUuidChange() {
        updateUuid();
        LogUtils.d("play post onresume and uuid changed: uuid is " + this.uuid);
    }

    public BigDataPlayReporter setCid(String cid) {
        this.cid = cid;
        return this;
    }

    public BigDataPlayReporter setPy(String name, String src) {
        StringBuilder sb = new StringBuilder();
        sb.append("name=").append(name).append("&src=").append(src);
        py = sb.toString();
        return this;
    }

    public BigDataPlayReporter setVid(String vid) {
        this.vid = vid;
        return this;
    }

    public String getVid() {
        return vid;
    }

    public BigDataPlayReporter setPid(String pid) {
        this.pid = pid;
        return this;
    }

    public BigDataPlayReporter setRef(String ref) {
        this.ref = ref;
        return this;
    }

    // 点播设置视频时长
    public BigDataPlayReporter setDuration(long duration) {
        this.duration = duration / 1000;
        return this;
    }

    // 直播设置视频时长（取较大值6000）
    public void setVlen() {
        duration = 6000;
    }

    public void setProgress(int progress) {
        this.progress = progress;
    }

    public void onProgress(int progress, long max) {
        this.progress = (int) (this.duration*progress/max);
    }

    /**
     * 播放类型，{@link BigDataConstants#TY_LOCAL},{@link BigDataConstants#TY_ONLINE},{@link BigDataConstants#TY_TVLINE}
     *
     * @param playType
     * @return
     */
    public BigDataPlayReporter setPlayType(String playType) {
        this.playType = playType;
        return this;
    }

    public BigDataPlayReporter setUrl(String url) {
        this.url = url;
        return this;
    }

    public BigDataPlayReporter setStreamType(String stream_type) {
        this.stream_type = stream_type;
        return this;
    }

    public void onPlayStart() {
        if (TextUtils.isEmpty(uuid)) {
            uuid = generateUUID() + "_0";
            LogUtils.e("wym", "onPlayStart() uuid is null and genUUid and cur uuid " + uuid);
        } else
            LogUtils.e("wym", "onPlayStart() uuid not null and uuid is " + uuid);
        isErrorReported = false;
        buffer_start = System.currentTimeMillis();
    }

    /**
     * 播放器初始化上报
     */
    public void onPlayerInit() {
        LogUtils.d("play post onPlayerInit");
        isBufferSuccess = false;
        BigDataStats.post(new BigDataPlayerInitTask());
    }

    public void onAdStart() {
        LogUtils.e("onAdstart");
        BigDataStats.post(new BigDataAdStartTask());
    }

    public void onAdEnd() {
        LogUtils.e("onAdEnd");
        BigDataStats.post(new BigDataAdEndTask());
    }

    /**
     * 播放开始上报
     */
    public void onBufferEnd() {
        LogUtils.d("play post onBufferEnd");
        isBufferSuccess = true;
        buffer_time = System.currentTimeMillis() - buffer_start;
        BigDataStats.post(new BigDataPlayStartTask());
    }

    /**
     * 播放心跳上报
     */
    public void onPlayTime() {
        LogUtils.d("play post onPlayTime");
        isBufferSuccess = true;
        buffer_time = System.currentTimeMillis() - buffer_start;
        BigDataStats.post(new BigDataPlayTimeTask());
    }

    /**
     * 播放过程上报
     */
    public void onPlayProcess() {
        LogUtils.d("play post onPlayProcess");
        isBufferSuccess = true;
        buffer_time = System.currentTimeMillis() - buffer_start;
        BigDataStats.post(new BigDataPlayerPlayProcessTask());
    }

    /**
     * 播放结束上报
     */
    public void onPlayEnd() {
        LogUtils.e("onPlayEnd() end called and cur uuid " + uuid);
        genUUID();
        LogUtils.d("play post onPlayEnd");
        BigDataStats.post(new BigDataPlayEndTask());
    }

    /**
     * 播放自然结束上报
     */
    public void onPlayFinish() {
        genUUID();
        LogUtils.d("play post onPlayFinish");
        BigDataStats.post(new BigDataPlayFinishTask());
    }

    /**
     * 播放暂停上报
     */
    public void onPlayPause() {
        genUUID();
        LogUtils.d("play post onPlayPause");
        BigDataStats.post(new BigDataPlayPauseTask());
    }

    /**
     * 播放拖拽上报
     */
    public void onPlayDrag() {
        genUUID();
        LogUtils.d("play post onPlayDrag");
        BigDataStats.post(new BigDataPlayDragTask());
    }

    /**
     * 播放暂停后恢复上报
     */
    public void onPlayResume() {
        genUUID();
        LogUtils.d("play post onPlayResume");
        BigDataStats.post(new BigDataPlayResumeTask());
    }
    /**
     * 播放切清晰度上报
     */
    public void onPlayTg() {
        genUUID();
        LogUtils.d("play post onPlayTg");
        BigDataStats.post(new BigDataPlayTgTask());
    }

    private void reset() {
        retry_time = 0;
        progress = 0;
        duration = 0;
        errorCode = "";
    }

    /**
     * 播放错误上报
     *
     * @param isLVideoSource true 乐视源 false 外站源
     * @param errCode        具体的播放错误类型
     */
    public void onPlayError(boolean isLVideoSource, String errCode) {
        if (isErrorReported) {
            return;
        }
        isErrorReported = true;
        if (isLVideoSource)
            errorType = BigDataConstants.PLAY_ERR;
        else
            errorType = "";
        errorCode = errCode;
        LogUtils.d("play post onPlayError");
        BigDataStats.post(new BigDataPlayErrorTask());
        isBufferSuccess = false;
    }

    /**
     * 生成uuid
     */
    public void genUUID() {
        if (StringUtil.isEmpty(uuid)) {
            uuid = generateUUID() + "_0";
        }
        LogUtils.e("genUUID() uuid not null and genUUid and cur uuid " + uuid);
    }

    /**
     * 重置uuid
     */
    public void resetUUID() {
        LogUtils.e("wym", "reset uuid and new uuid is " + uuid);
        uuid = generateUUID() + "_0";
    }

    private String generateUUID() {
        return UUID.randomUUID().toString();
    }

}
